package com.lbc.cas;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

//  原子引用解决ABA问题
public class ABADems {
    public static void main(String[] args) {
        //  AtomicInteger atomicInteger = new AtomicInteger(2020);

        //  AtomicStampedReference 注意：如果泛型是一个包装类，注意对象当代引用问题
        //  <>中的Integer默认的范围是 -128~127
        //  正常的业务操作，这里面比较的都是一个个对象
        AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(11, 1);

        //  和乐观锁的原理相同
        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();  //  获取版本号
            System.out.println("a1=>"+stamp);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(atomicStampedReference.compareAndSet(11, 22,
                    atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));

            System.out.println("a2=>"+atomicStampedReference.getStamp());

            System.out.println(atomicStampedReference.compareAndSet(22, 11,
                    atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1));

            System.out.println("a3=>"+atomicStampedReference.getStamp());
            },"a").start();

        new Thread(()->{
            int stamp = atomicStampedReference.getStamp();
            System.out.println("b1=>"+stamp);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(atomicStampedReference.compareAndSet(11, 66,
                    stamp, stamp + 1));  //  注意，这里的版本号不是动态的

            System.out.println("b2=>"+atomicStampedReference.getStamp());
        },"b").start();
    }
}
